package com.atguigu.config;

import com.atguigu.bean.Car;
import com.atguigu.bean.Color;
import com.atguigu.dao.BookDao;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

/**
 * 自动装配:
 *      Spring利用依赖注入(DI),完成对IOC容器中各个组件的依赖关系赋值;
 *
 *  1).@Autowired:自动注入,默认优先按照类型去容器中找对应的组件
 *          (1) 按类型注入的时候,默认优先去容器中招对应的组件:applicationContext.getBean(BookDao.class)
 *          (2) 如果找到多个相同的组件,再将属性的名称作为组件的id去容器中查找
 *                          applicationContext.getBean(BookDao.class)
 *          (3) @Qualifier("bookDao"),使用@Qualifier指定需要装配的组件id,而不是使用属性名
 *          (4) 自动装配,默认一定要将属性赋值好,没有就会报错。
 *              可以使用@Autowired(required=false)
 *
 *          (5) @Primary: 让Spring进行自动装配的时候,默认使用@Primary首选的bean
 *                          同时,记得注释掉@Qualifier
 *
 *          BookService {
 *              @Autowried
 *              BookDao bookDao;
 *          }
 *
 *  2). Spring还支持@Resource(JSR250)和@Inject(JSR330)[java规范的注解]
 *                  @Resource:
 *                      可以和@Autowired一样实现自动装配功能,默认是按照组件名称进行装配的
 *                      没有能支持@Primary功能没有支持，没有支持@Autowired(reqiured=false)
 *                  @Inject:
 *                      需要导入java.Inject的jar包,和@Autowried一样,都是按类型注入,没有required=false的功能。
 *          @Autowried是Spring定义的,@Resource,@Inject都是Java规范
 *
 *  参考代码BookService
 *
 *  AutowiredAnnotationBeanPostProcessor:解析完成自动装配功能
 *
 *  3) @Autowried:构造器,参数,方法,属性;
 *          参考代码Boss
 *          1). @Autowired可以标注在方法位置,会按参数名去自动注入
 *          2). 放在构造器上: 如果组件只有一个有参构造器,这个有参构造器@Autowired可以省略,参数位置的组件还是可以自动从容器中获取
 *          3). 放在形参列表上
 *          4). 不管怎么放,都是从IOC容器中获取组件的值
 *          5). 放在方法位置:@Bean+方法参数:参数从容器中获取;默认不写@Autowired效果是一样的;都能自动装配
 *
 *  4).自定义组件想要使用Spring容器底层的一些组件(ApplicationContext,BeanFactory,xxx);
 *          自定义组件实现xxxAware;在创建对象的时候,会调用接口规定的方法注入相关组件。
 *          把Spring底层一些组件注入到自定义的Bean中
 *
 *      参考代码Red
 *
 *
 *
 */

@Configuration
@ComponentScan({"com.atguigu.service","com.atguigu.dao","com.atguigu.controller","com.atguigu.bean"})
public class MainConfigOfAutowired {

    @Primary
    @Bean("bookDao2")
    public BookDao bookDao() {
        BookDao bookDao = new BookDao();
        bookDao.setLable("2");
        return bookDao;
    }

    /**
     * @Bean标注的方法创建对象的时候,方法参数的值从容器中自动获取
     * @param car
     * @return
     */
    @Bean
    public Color color(Car car) {
        return new Color();
    }

}
